package com.abel.bigwater.dataserver.model.qdies

import com.abel.bigwater.data.BcdString
import com.abel.bigwater.dataserver.model.PacketCmdException
import com.abel.bigwater.model.JsonDateDeserializer
import com.abel.bigwater.model.JsonDateSerializer
import com.abel.bigwater.model.JsonHelper
import com.alibaba.fastjson.annotation.JSONField
import com.fasterxml.jackson.databind.annotation.JsonDeserialize
import com.fasterxml.jackson.databind.annotation.JsonSerialize
import io.netty.buffer.ByteBuf
import org.joda.time.DateTime
import java.util.*

/**
 * 读取D10当前时间
上位机发送： 帧头 地址 0x02 0x00 校验 帧尾
D10应答： 帧头 地址 0x02 0x07 年 月 日 时 分 秒 星期 校验 帧尾
 */
open class DtenAskTimeData(_len: Int) : D10BaseData(_len) {
    companion object {
        const val MIN_LEN = 7
    }

    override var type = FuncType.AskTime

    @JsonSerialize(using = JsonDateSerializer::class)
    @JsonDeserialize(using = JsonDateDeserializer::class)
    @JSONField(format = JsonHelper.FULL_DATE_FORMAT)
    var time: Date? = null

    var timeBcd: BcdString? = null

    override fun fill(buf: ByteBuf) {
        if (time == null) {
            time = Date()
        }

        val dt = DateTime(time)
        timeBcd = BcdString(byteArrayOf(dt.year.rem(100).toByte(),
                dt.monthOfYear.toByte(),
                dt.dayOfMonth.toByte(),
                dt.hourOfDay.toByte(),
                dt.minuteOfHour.toByte(),
                dt.secondOfMinute.toByte(),
                dt.dayOfWeek.toByte()), true)
        buf.writeBytes(timeBcd!!.hexArray)
    }

    override fun parse(buf: ByteBuf): Boolean {
        if (buf.readableBytes() < MIN_LEN) throw PacketCmdException("should contain y/m/d h/m/s w")

        buf.duplicate().apply {
            timeBcd = BcdString.create(this, 6)
            val dt = DateTime(timeBcd!!.bcdArray!![0] + DateTime.now().year / 100 * 100,
                    timeBcd!!.bcdArray!![1].toInt(),
                    timeBcd!!.bcdArray!![2].toInt(),
                    timeBcd!!.bcdArray!![3].toInt(),
                    timeBcd!!.bcdArray!![4].toInt(),
                    timeBcd!!.bcdArray!![5].toInt())
            val wd = readByte().toInt()
            if (dt.dayOfWeek != wd) {
                throw PacketCmdException("week day: ${dt.dayOfWeek} != $wd")
            }

            time = dt.toDate()
        }

        buf.skipBytes(MIN_LEN)

        return true
    }

    override fun count(): Int = MIN_LEN
}